package de.unikoblenz.west.csxpoi;

import java.util.ArrayList;
import java.util.List;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * Encapsulates categories, which are identified by their URI and have a name,
 * superclasses, subclasses, and equivalents.
 */
public class CategoryWrapper implements Parcelable {

	/**
	 * the URI of the category
	 */
	private String mUri = null;

	/**
	 * the name of the category
	 */
	private String mName = null;

	/**
	 * the list of superclasses of the category
	 */
	private List<CategoryWrapper> mSuperclasses = new ArrayList<CategoryWrapper>();

	/**
	 * the list of subclasses of the category
	 */
	private List<CategoryWrapper> mSubclasses = new ArrayList<CategoryWrapper>();

	/**
	 * the list of equivalents of the category
	 */
	private List<CategoryWrapper> mEquivalents = new ArrayList<CategoryWrapper>();

	/**
	 * Creates a category with the specified name by retrieving the URI from the
	 * ontology.
	 * 
	 * @param name
	 *            the name of the category
	 * @return a category with the specified name and the corresponding URI or
	 *         null if no URI can be found
	 */
	public static CategoryWrapper createFromName(String name) {
		CategoryWrapper category = new CategoryWrapper();
		category.setName(name);
		category.setUri(OntologyBuffer.getUriForCategoryName(name));
		return category;
	}

	/**
	 * Gets the URI of the category
	 * 
	 * @return the URI of the category
	 */
	public String getUri() {
		return mUri;
	}

	/**
	 * Gets the name of the category
	 * 
	 * @return the name of the category
	 */
	public String getName() {
		return mName;
	}

	/**
	 * Gets the superclasses of the category
	 * 
	 * @return a copy of the list of superclasses of the category
	 */
	public List<CategoryWrapper> getSuperclasses() {
		return new ArrayList<CategoryWrapper>(mSuperclasses);
	}

	/**
	 * Gets the subclasses of the category
	 * 
	 * @return a copy of the list of subclasses of the category
	 */
	public List<CategoryWrapper> getSubclasses() {
		return new ArrayList<CategoryWrapper>(mSubclasses);
	}

	/**
	 * Gets the equivalents of the category
	 * 
	 * @return a copy of the list of equivalents of the category
	 */
	public List<CategoryWrapper> getEquivalents() {
		return new ArrayList<CategoryWrapper>(mEquivalents);
	}

	/**
	 * Sets the URI of the category
	 * 
	 * @param uri
	 *            the URI to set
	 */
	public void setUri(String uri) {
		mUri = uri;
	}

	/**
	 * Sets the name of the category
	 * 
	 * @param name
	 *            the name to set
	 */
	public void setName(String name) {
		mName = name;
	}

	/**
	 * Adds a superclass to the category.
	 * 
	 * @param superclass
	 *            the superclass to add
	 */
	public void addSuperclass(CategoryWrapper superclass) {
		mSuperclasses.add(superclass);
	}

	/**
	 * Adds a subclass to the category.
	 * 
	 * @param subclass
	 *            the subclass to add
	 */
	public void addSubclass(CategoryWrapper subclass) {
		mSubclasses.add(subclass);
	}

	/**
	 * Adds an equivalent to the category
	 * 
	 * @param equivalent
	 *            the equivalent to add
	 */
	public void addEquivalent(CategoryWrapper equivalent) {
		mEquivalents.add(equivalent);
	}

	/**
	 * The category's name is its string representation.
	 */
	@Override
	public String toString() {
		return mName;
	}

	/**
	 * Categories are equal if their URIs match.
	 */
	@Override
	public boolean equals(Object object) {
		try {
			CategoryWrapper category = (CategoryWrapper) object;
			return mUri.equals(category.getUri());
		} catch (ClassCastException e) {
			return false;
		} catch (NullPointerException e) {
			return false;
		}
	}

	/**
	 * Handles the creation of a category or an array of categories from a
	 * parcel.
	 */
	public static Parcelable.Creator<CategoryWrapper> CREATOR = new Creator<CategoryWrapper>() {

		/**
		 * Creates a category from the specified parcel.
		 */
		public CategoryWrapper createFromParcel(Parcel source) {
			CategoryWrapper category = new CategoryWrapper();
			category.setUri(source.readString());
			category.setName(source.readString());
			// TODO: superclasses/subclasses/equivalents
			return category;
		}

		/**
		 * Creates an empty array of categories of the specified size.
		 */
		public CategoryWrapper[] newArray(int size) {
			CategoryWrapper[] categories = new CategoryWrapper[size];
			for (int i = 0; i < size; i++) {
				categories[i] = new CategoryWrapper();
			}
			return categories;
		}
	};

	/**
	 * Handles the creation of a parcel for the category.
	 */
	public void writeToParcel(Parcel out, int flags) {
		out.writeString(mUri);
		out.writeString(mName);
		// TODO: superclasses/subclasses/equivalents
	}

	/**
	 * No special objects are contained.
	 */
	public int describeContents() {
		return 0;
	}

}
